#!/usr/bin/env julia

using TongLun

# Test basic functionality
function test_basic_types()
    println("Testing basic types...")
    
    # Test export and call with basic types
    TongLun.export_fn("test.add", (a, b) -> a + b)
    TongLun.export_fn("test.multiply", (a, b) -> a * b)
    TongLun.export_fn("test.concat", (a, b) -> string(a, b))
    TongLun.export_fn("test.complex_add", (a, b) -> a + b)
    
    # Test calling exported functions
    result1 = TongLun.call_fn("test.add", 1, 2)
    println("1 + 2 = $result1")
    @assert result1 === 3
    
    result2 = TongLun.call_fn("test.multiply", 3.5, 2.0)
    println("3.5 * 2.0 = $result2")
    @assert result2 === 7.0
    
    result3 = TongLun.call_fn("test.concat", "Hello, ", "World!")
    println("Concat: $result3")
    @assert result3 == "Hello, World!"
    
    result4 = TongLun.call_fn("test.complex_add", 1+2im, 3+4im)
    println("(1+2i) + (3+4i) = $result4")
    @assert result4 === ComplexF64(4, 6)
    
    println("✅ Basic types test passed!")
end

function test_arrays()
    println("Testing arrays...")
    
    # Test array functions
    TongLun.export_fn("test.array_sum", sum)
    TongLun.export_fn("test.array_mean", arr -> sum(arr) / length(arr))
    TongLun.export_fn("test.array_shape", size)
    TongLun.export_fn("test.matrix_transpose", transpose)
    
    # Test 1D array
    arr1d = [1.0, 2.0, 3.0, 4.0, 5.0]
    result_sum = TongLun.call_fn("test.array_sum", arr1d)
    println("Sum of $arr1d = $result_sum")
    @assert result_sum === 15.0
    
    result_mean = TongLun.call_fn("test.array_mean", arr1d)
    println("Mean of $arr1d = $result_mean")
    @assert result_mean === 3.0
    
    # Test 2D array
    arr2d = [1.0 2.0 3.0; 4.0 5.0 6.0]
    result_shape = TongLun.call_fn("test.array_shape", arr2d)
    println("Shape of $arr2d = $result_shape")
    @assert result_shape == (2, 3)
    
    result_transpose = TongLun.call_fn("test.matrix_transpose", arr2d)
    println("Transpose of $arr2d = $result_transpose")
    @assert result_transpose == transpose(arr2d)
    
    println("✅ Arrays test passed!")
end

function test_tuples()
    println("Testing tuples...")
    
    # Test tuple functions
    TongLun.export_fn("test.tuple_length", length)
    TongLun.export_fn("test.tuple_first", first)
    TongLun.export_fn("test.tuple_last", last)
    TongLun.export_fn("test.make_tuple", (a, b, c) -> (a, b, c))
    
    # Test tuple operations
    test_tuple = (1, "hello", 3.14, true)
    result_length = TongLun.call_fn("test.tuple_length", test_tuple)
    println("Length of $test_tuple = $result_length")
    @assert result_length === 4
    
    result_first = TongLun.call_fn("test.tuple_first", test_tuple)
    println("First of $test_tuple = $result_first")
    @assert result_first === 1
    
    result_last = TongLun.call_fn("test.tuple_last", test_tuple)
    println("Last of $test_tuple = $result_last")
    @assert result_last === true
    
    result_make = TongLun.call_fn("test.make_tuple", "a", 42, false)
    println("Made tuple = $result_make")
    @assert result_make == ("a", 42, false)
    
    println("✅ Tuples test passed!")
end

function test_mixed_types()
    println("Testing mixed types...")
    
    # Test function that works with mixed types
    TongLun.export_fn("test.describe", x -> "$(typeof(x)): $x")
    TongLun.export_fn("test.process_mixed", function(data)
        if isa(data, Number)
            return data * 2
        elseif isa(data, AbstractString)
            return uppercase(data)
        elseif isa(data, AbstractArray)
            return length(data)
        elseif isa(data, Tuple)
            return length(data)
        else
            return "unknown type"
        end
    end)
    
    # Test various types
    test_cases = [42, 3.14, "hello", [1, 2, 3, 4], (1, 2, 3)]
    
    for case in test_cases
        desc = TongLun.call_fn("test.describe", case)
        processed = TongLun.call_fn("test.process_mixed", case)
        println("$case -> described as: $desc, processed as: $processed")
    end
    
    println("✅ Mixed types test passed!")
end

function test_error_handling()
    println("Testing error handling...")
    
    # Test function that throws an error
    TongLun.export_fn("test.divide", (a, b) -> b == 0 ? error("Division by zero!") : a / b)
    
    # Test normal case
    result = TongLun.call_fn("test.divide", 10.0, 2.0)
    println("10.0 / 2.0 = $result")
    @assert result === 5.0
    
    # Test error case
    try
        TongLun.call_fn("test.divide", 10.0, 0.0)
        @assert false "Should have thrown an error"
    catch e
        println("Caught expected error: $e")
        @assert isa(e, TongLun.TonglunError)
    end
    
    println("✅ Error handling test passed!")
end

function main()
    println("Running TongLun Julia binding tests...")
    println("=" ^ 50)
    
    try
        test_basic_types()
        test_arrays()
        test_tuples()
        test_mixed_types()
        test_error_handling()
        
        println("=" ^ 50)
        println("🎉 All tests passed successfully!")
        
    catch e
        println("❌ Test failed with error: $e")
        println(stacktrace())
        exit(1)
    end
end

if abspath(PROGRAM_FILE) == @__FILE__
    main()
end 